/**
 * @file command_line_parser.h
 * @brief Parse the commands passed to the program at startup.
 *
 * If you want to add extra commands, please edit function: registerOptions(), handleOption(...) and printHelp(),
 * and add other members you need.
 */

#pragma once

#include <vector>
#include <string>
#include <unordered_map>
#include <memory>
#include <iostream>

class CommandLineParser {
 public:
    CommandLineParser();

    /// @brief Main parsing function
    bool parse(int argc, char* argv[]);

    /// Access parsed values
    bool hasHelp() const { return m_showHelp; }
    bool hasVersion() const { return m_showVersion; }
    bool listDevices() const { return m_listDevices; }

    const std::vector<std::string>& getDevices() const { return m_devices; }
    const std::string& getFilter() const { return m_filter; }
    const std::string& getRulesFile() const { return m_rulesFile; }
    const std::string& getLogLevel() const { return m_logLevel; }
    const std::string& getLogFile() const { return m_logFile; }

    int getBufferSize() const { return m_bufferSize; }
    int getTimeOut() const { return m_timeout; }
    int getWorkers() const { return m_workers; }
    int getBatchSize() const { return m_batchSize; }

    bool isPromiscuous() const { return m_promiscuous; }
    bool isConsoleOnly() const { return m_consoleOnly; }
    bool isQuiet() const { return m_quiet; }
    bool isVerbose() const { return m_verbose; }
    bool isTestMode() const { return m_testMode; }
    bool isDryRun() const { return m_dryRun; }
    bool isDaemon() const { return m_daemon; }

    /// Help and version information
    void printHelp() const;
    void printVersion() const;

 private:
    /// @brief Option definition structure
    struct Option {
        std::string longName;
        char shortName;
        std::string description;
        bool requiresArgument;
        std::string argumentName;
    };

    /// Parsing state
    bool m_showHelp = false;
    bool m_showVersion = false;
    bool m_listDevices = false;

    std::vector<std::string> m_devices;
    std::string m_filter;
    std::string m_rulesFile;
    std::string m_logLevel = "info";
    std::string m_logFile;

    int m_bufferSize = 64 * 1024 * 1024;    /// 64MB
    int m_timeout = 100;                    /// milliseconds
    int m_workers = 4;
    int m_batchSize = 100;

    bool m_promiscuous = true;
    bool m_consoleOnly = false;
    bool m_quiet = false;
    bool m_verbose = false;
    bool m_testMode = false;
    bool m_dryRun = false;
    bool m_daemon = false;

    /// Option registry
    std::vector<Option> m_options;
    std::unordered_map<std::string, Option> m_longOptionMap;
    std::unordered_map<char, Option> m_shortOptionMap;

    /// Internal methods
    void registerOptions();
    void registerOptions(const std::string& longName, char shortName,
                         const std::string& description,
                         bool requiresArgument = false,
                         const std::string& argumentName = "");
    bool handleOption(const std::string& option, const std::string& value = "");
    void validateOptions();

    /// Utility functions
    static bool startWith(const std::string& str, const std::string& prefix);
};